package br.ufpe.abaco.ParserGen.parser;
import java.io.*;
/**
 *  Esta classe representa um item LR(0) de uma gramatica.
 *
 *@author     Monique Monteiro e Pablo Sampaio
 *@created    30 de Outubro de 2002
 */
class LRItem implements Serializable {
    /*
     *  producao a qual o item LR(0) se refere
     */
    /**
     *  Description of the Field
     */
    public final Production production;
    /*
     *  indica a posicao do ponto no lado direito da producao
     */
    /**
     *  Description of the Field
     */
    public final int position;
    /*
     *  numero utilizado ordenar os items, alem de ser utilizado como codigo de hash
     */
    final int ordem;

    GrammarSymbol acceptedSym;
    LRItem next;


    /**
     *  Construtor da classe LRItem. So deve ser chamado pela classe Production.
     *
     *@param  prod  Description of the Parameter
     *@param  pos   Description of the Parameter
     */
    LRItem(Production prod, int pos) {
        this.production = prod;
        this.position = pos;
        this.ordem = 10 * production.index + position;
        if (pos < production.getRightSide().length) {
            acceptedSym = production.getRightSide()[pos];
        } else {
            acceptedSym = null;
        }
    }


    /**
     *  Implementacao do hash code para poder usar LRItem como chave de tabelas
     *  hash.
     *
     *@return    Description of the Return Value
     */
    public int hashCode() {
        return this.ordem;
    }


    /**
     *  Description of the Method
     *
     *@param  o  Description of the Parameter
     *@return    Description of the Return Value
     */
    public boolean equals(Object o) {
        //return this==o; //nao seria a mesmo coisa que usar o equals de Object?
        if (o != null && o instanceof LRItem) {
            LRItem item = (LRItem) o;
            return (this.position == item.position && this.production.equals(item.production));
        } else {
            return false;
        }
    }


    /**
     *  Description of the Method
     *
     *@return    Description of the Return Value
     */
    public String toString() {
        StringBuffer buffer = new StringBuffer(this.production.getLeftSide().toString());
        GrammarSymbol[] rightSide = this.production.getRightSide();

        buffer.append(" ::= ");

        for (int i = 0; i < this.position; i++) {
            buffer.append(' ');
            buffer.append(rightSide[i].toString());
        }

        buffer.append('.');

        for (int i = this.position; i < rightSide.length; i++) {
            buffer.append(' ');
            buffer.append(rightSide[i].toString());
        }

        return buffer.toString();
    }

}

